--[[
	SpellTips 3.0

	This mod adjusts spell tooltips to reflect +Damage and +Healing
	Made by Gandros on Ner'Zhul.
	Formerly known as Cera on Magtheridon.

	Feel free to edit or use any part of this code.
]]


SpellTips = {}
_, SpellTips.Class = UnitClass("player")



function SpellTips:OnLoad()

	self.RealmName = GetCVar("realmName")
	if (self.RealmName == "Magtheridon" or self.RealmName == "Ner'zhul") then
		this:RegisterEvent("UPDATE_MOUSEOVER_UNIT")
	end

	for i in pairs(SpellTips.SpellsLocal) do
		for key,value in pairs(SpellTips.SpellsLocal[i]) do SpellTips.Spells[i][key]=value end
	end
	
--	local spells = {}
--	for i in pairs(SpellTips.Spells) do
--		for key,value in pairs(SpellTips.Spells[i]) do spells[i][key]=value end
--	end
	
--	local talents = {}
--	for i in pairs(SpellTips.Talents) do talents[i]=SpellTips.Talents[i] end

	self:GetTalents()
	this:RegisterEvent("PLAYER_ALIVE")
	this:RegisterEvent("CHARACTER_POINTS_CHANGED")

	hooksecurefunc(GameTooltip, "SetSpell", self.Main)
	hooksecurefunc(GameTooltip, "SetAction", self.Main)
	hooksecurefunc(GameTooltip, "SetPetAction", self.Main)
	hooksecurefunc(GameTooltip, "SetTrainerService", self.Main)
end

function SpellTips:OnEvent()

	if (event == "UPDATE_MOUSEOVER_UNIT") then
		if (UnitName("mouseover")) then
			self:UnitFormat("mouseover")
		end
	elseif (event == "PLAYER_ALIVE") then				-- Best event I could find for talents to be valid at startup
		self:GetTalents()
	elseif (event == "CHARACTER_POINTS_CHANGED") then
		self:GetTalents()
	end
end


--Spell MouseOver Routine---------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------
function SpellTips.Main()

	local ST_name, ST_rank = GameTooltip:GetSpell()
	if (ST_name == nil) then return end
	
	for i in pairs(SpellTips.Spells) do
		if (ST_name == SpellTips.Spells[i].name) then
			local pattern = SpellTips.Spells[i].pattern
			local pattern2 = SpellTips.Spells[i].pattern2
			local ST_spell_text = GameTooltipTextLeft4:GetText() or ""
				
            	-- Check for short text (totem/shard/cooldown) on line 4
			if (string.len(ST_spell_text) < 30) then
				SpellTips.SpellLine = getglobal("GameTooltipTextLeft5")
				ST_spell_text = SpellTips.SpellLine:GetText()
			else
                  	SpellTips.SpellLine = getglobal("GameTooltipTextLeft4")
			end
				
			-- Calculate bonus and add it to the tooltip
			if (ST_spell_text ~= nil) then
				local boost, base, fixbase, fixbase2 = 0,0,0,0
				local text = ST_spell_text
				local _, _, base = string.find(ST_spell_text, pattern)

				if (SpellTips.Spells[i].school == 1) then
					boost = GetSpellBonusHealing() * 1.88 or 0
				else
					boost = GetSpellBonusDamage(SpellTips.Spells[i].school) or 0
				end

				boost = boost * SpellTips:GetTalentBoost(i)					-- Multiply by talent coefficient
				boost = boost * SpellTips.Spells[i].bonus						-- Multiply by spell coefficient
				boost = SpellTips:Downscale(i,boost,tonumber(ST_rank))			-- Multiply by rank coefficient

				if (base == nil) then
					text = ST_spell_text;
				else
--					if (SpellTips.Spells[i].school == 1) then					-- Hack to fix base of heals
--						fixbase = SpellTips:Round(base * SpellTips:GetTalentBoost(i) - base) or 0
--					end

					local adjusted = base + boost + fixbase
					text = string.gsub(ST_spell_text, base, adjusted, 1)
				end

				if (pattern2 ~= nil) then
					local _, _, base2 = string.find(text, pattern2)
					if (base2 == nil) then base2 = 0 end

--					if (SpellTips.Spells[i].school == 1) then					-- Hack to fix base of heals
--						fixbase2 = SpellTips:Round(base2 * SpellTips:GetTalentBoost(i) - base2) or 0
--					end

					local adjusted2 = base2 + boost + fixbase2
					local text2 = string.gsub(text, base2, adjusted2, 1)
					SpellTips.SpellLine:SetText(text2)
				else
					SpellTips.SpellLine:SetText(text)
				end
			end

			GameTooltip:Show()

                  -- Let it loop 1 more time after a match in case it's a dd+dot spell
			if (ST_break ~= nil) then
				ST_break = 0
				break
			else
				local ST_break = 1
			end
		end
	end
end


--Talent Routines-----------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------
function SpellTips:GetTalents()

	for i in pairs(SpellTips.Talents) do
		local _, _, _, _, currRank, _ = GetTalentInfo(SpellTips.Talents[i].tree,SpellTips.Talents[i].branch)
		SpellTips.Talents[i].current = currRank * SpellTips.Talents[i].coefficient
	end
	SpellTips.Level = UnitLevel("player")							-- If talents changed then player level may have
end

function SpellTips:GetTalentBoost(index)

	local coefficient = 1
	for i in pairs(SpellTips.Spells[index].talents) do
		coefficient = coefficient * (1 + SpellTips.Talents[SpellTips.Spells[index].talents[i]].current)
	end
	return coefficient
end


--Downranking Routine-------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------
function SpellTips:Downscale(index,damage,rank)

	if SpellTips.Spells[index].levels then
		local level = SpellTips.Spells[index].levels[rank] or SpellTips.Level	-- Set to player's level if unknown
		local coefficient = (level + 5) / SpellTips.Level				-- Max level assumed 1 less than next trained rank
		if (coefficient > 1) then coefficient = 1 end					-- Don't raise it!
		return SpellTips:Round(damage * coefficient)
	else
		return SpellTips:Round(damage)
	end
end


--Unit MouseOver Routine----------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------
function SpellTips:UnitFormat(unit)

	local name = UnitName(unit)
	if (self.RealmName == "Magtheridon" and (name == "Cera" or name == "Serrated"
	 or name == "Aflack" or name == "Chizzy" or name == "Oren" or name == "Broox"
	 or name == "Nemoe" or name == "Alterity" or name == "Margera" or name == "Ariakas"
	 or name == "Ghostwolf" or name == "Lexipie" or name == "Shonuff")) then
		if (name == "Aflack") then
			GameTooltip:AddLine("|cffBB55BBGayer than AIDS|r")
		elseif (name == "Chizzy") then
			GameTooltip:AddLine("Melter of Faces")
		elseif (name == "Oren") then
			GameTooltip:AddLine("\"Trinkets\"")
		elseif (name == "Broox") then
			GameTooltip:AddLine("Still owes Cera some Ben & Jerry's")
		elseif (name == "Nemoe") then
			GameTooltip:AddLine("Did your balls drop ".. UnitName("player") .."?")
		elseif (name == "Thormx") then
			GameTooltip:AddLine("Got crabs at Dirty Dicks")
		elseif (name == "Alterity") then
			GameTooltip:AddLine("Spoons Margera")
		elseif (name == "Margera") then
			GameTooltip:AddLine("Spoons Alterity")
		elseif (name == "Ghostwolf") then
			GameTooltip:AddLine("Doesn't go to you.")
		elseif (name == "Ariakas") then
			GameTooltip:AddLine("Pink Socked Lexi")
		elseif (name == "Lexipie") then
			GameTooltip:AddLine("Which brother is it!?")
		elseif (name == "Shonuff") then
			GameTooltip:AddLine("|cffff00ffJ|r|cffff0066u|r|cffff6600n|r|cffffff00g|r|cff6600ffl|r|cff66ff00e|r Balls")
		elseif (date("%m") == "12") then
			GameTooltip:AddLine("|cff00ff00Santa's Mistress|r")
		else
			GameTooltip:AddLine("Author of SpellTips")
		end
	end
	if (self.RealmName == "Ner'zhul" and name == "Gandros") then
		if (date("%m") == "12") then
			GameTooltip:AddLine("|cff00ff00Santa's|r |cffff0000Angriest|r |cff00ff00Helper|r")
		else
			GameTooltip:AddLine("Author of SpellTips")
		end
	end
	GameTooltip:Show();
end


--Rounding Routine----------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------
function SpellTips:Round(x)

	if (x > 0) then
		return math.floor(x+0.5)
	else
		return math.ceil(x-0.5)
	end
end


--Debuging Routine----------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------
function SpellTips:Debug(string)

	DEFAULT_CHAT_FRAME:AddMessage(tostring(string))
end
